﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Spider_Compiler.Properties;

//Copyright (C) 2010 Florian Kolb

//This program is free software; you can redistribute it and/or modify it under the terms 
//of the GNU General Public License as published by the Free Software Foundation; either 
//version 2 of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
//without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
//See the GNU General Public License for more details.

//You should have received a copy of the GNU General Public License along with this program; 
//if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 

namespace Spider_Compiler
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "Spider Compiler";

            Console.WriteLine("Spider Compiler Version 1.00");
            Console.WriteLine(new string('=', 30));
            Console.WriteLine("Copyright (c) Florian Kolb 2010");
            Console.WriteLine();

            if (Environment.GetCommandLineArgs().Count() > 1)
            {
                InterpreteCommands(Environment.GetCommandLineArgs());
            }
            else
            {
                //ONLY FOR DEBUG!!!
                InterpreteCommands(new string[] { "-c", "test.spider" });
            }

            Console.ReadLine();
        }

        private static void InterpreteCommands(string[] args)
        {
            if (args != null && args.Count() > 0)
            {
                for (int i = 0; i < args.Count(); i++)
                {
                    switch (args[i])
                    {
                        case "-i":
                        case "-?":
                            Console.WriteLine("Help for spider compiler");
                            Console.WriteLine("Commandline arguments for use:");
                            Console.WriteLine("-i or -?\tShows this help");
                            Console.WriteLine("-c [file]\tCompiles the file (*.spider) into a exe-file");
                            Console.WriteLine("-l\t\tShows the license");
                            break;
                        case "-c":
                            if ((args.Count() - 1) > i++)
                            {
                                CompileFile(args[i++]);
                            }
                            else
                            {
                                Error("No input source file specified!");
                            }
                            break;
                        case "-l":
                            Console.Write(Resources.GPLv2License);
                            break;
                    }
                }
            }
        }

        private static void CompileFile(string file)
        {
            if (file.EndsWith(".spider"))
            {
                string[] expressions = File.ReadAllLines(file);
                //Parse the source code
                Parser p = new Parser();
                p.Error += ParserError;
                Console.WriteLine("Parsing source file '{0}'...", file);
                List<CompilerInstruction> instructions = p.ParseExpressions(expressions);
                
                //Compile only if the parser didn't throw a error
                if (p.ErrorCount == 0)
                {
                    Console.WriteLine("Successfully parsed!");
                    Compiler c = new Compiler(instructions, string.Format("{0}.exe", Path.GetFileName(file.Remove(file.LastIndexOf(".")))));
                    c.Progress += CompilerProgress;
                    c.Finished += CompilerFinished;
                    c.Compile();
                }
                else
                {
                    Error("Compiler exited with {0} errors", p.ErrorCount);
                }
            }
            else if (!file.EndsWith(".spider"))
            {
                Error("The extension of the file '{0}' is not a valid spider source file extension!", file);
            }
        }

        private static void SetRedFont(Action action)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            action.Invoke();
            Console.ForegroundColor = ConsoleColor.White;
        }

        private static void Error(string message)
        {
            SetRedFont(new Action(delegate
            {
                Console.WriteLine(message);
            }));
        }

        private static void Error(string message, params object[] args)
        {
            SetRedFont(new Action(delegate
            {
                Console.WriteLine(message, args);
            }));
        }

        private static void ParserError(string error)
        {
            SetRedFont(new Action(delegate
            {
                Console.WriteLine(error);
            }));
        }

        private static void CompilerProgress(string message)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(message);
            Console.ForegroundColor = ConsoleColor.White;
        }

        private static void CompilerFinished()
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Compiled!");
            Console.ForegroundColor = ConsoleColor.White;
        }
    }
}
